package com.redissession.demo.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;


import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
 
/** 
*  
* @author sandsa redis cache service 
* 
*/  
 
@Configuration
@EnableCaching

public class RedisConfig extends CachingConfigurerSupport {
 
   @Autowired
   private RedisConn redisConn;  
     
   /** 
    * 生产key的策略 
    *  
    * @return 
    */  
 
   @Bean
   @Override  
   public KeyGenerator keyGenerator() {
       return new KeyGenerator() {  
 
           @Override  
           public Object generate(Object target, Method method, Object... params) {  
               StringBuilder sb = new StringBuilder();  
               sb.append(target.getClass().getName());  
               sb.append(method.getName());  
               for (Object obj : params) {  
                   sb.append(obj.toString());  
               }  
               return sb.toString();  
           }  
       };  
 
   }  
 
   /** 
    * 管理缓存 
    *  
    * @param redisTemplate 
    * @return 
    */  
 
   @SuppressWarnings("rawtypes")  
   @Bean  
   public CacheManager cacheManager(RedisTemplate redisTemplate) {
       RedisCacheManager rcm;
       rcm = new RedisCacheManager( redisTemplate);
       // 设置cache过期时间,时间单位是秒  
       rcm.setDefaultExpiration(60);  
       Map<String, Long> map = new HashMap<String, Long>();  
       map.put("test", 60L);  
       rcm.setExpires(map);  
       return rcm;  
   }  
     
   /** 
    * redis 数据库连接池 
    * @return 
    */  
 
   @Bean  
   public JedisConnectionFactory redisConnectionFactory() {
       JedisConnectionFactory factory = new JedisConnectionFactory();  
       factory.setHostName(redisConn.getHost());  
       factory.setPort(redisConn.getPort());  
       factory.setTimeout(redisConn.getTimeout());
       // 设置连接超时时间
       return factory;  
   }  
 
   /** 
    * redisTemplate配置 
    *  
    * @param factory 
    * @return 
    */  
   @SuppressWarnings({ "rawtypes", "unchecked" })  
   @Bean  
   public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
       StringRedisTemplate template = new StringRedisTemplate(factory);
       Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
       ObjectMapper om = new ObjectMapper();
       om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
       om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  
       jackson2JsonRedisSerializer.setObjectMapper(om);  
       template.setValueSerializer(jackson2JsonRedisSerializer);  
       template.afterPropertiesSet();  
       return template;  
   }  
 
}